import { Request, Response } from 'express';
import { Book, IBook } from '../models/book.model';
import { logger } from '../utils/logger';

/**
 * 图书管理控制器
 * 实现图书的 CRUD 操作
 */

/**
 * GET /api/books
 * 查询所有图书信息
 * 支持分页、排序和筛选
 */
export const getAllBooks = async (req: Request, res: Response): Promise<void> => {
  try {
    // 获取查询参数
    const page = parseInt(req.query.page as string) || 1;
    const limit = parseInt(req.query.limit as string) || 10;
    const sortBy = (req.query.sortBy as string) || 'createdAt';
    const order = (req.query.order as string) || 'desc';
    const category = req.query.category as string;
    const author = req.query.author as string;
    const keyword = req.query.keyword as string;

    // 构建查询条件
    const query: any = {};
    if (category) {
      query.category = category;
    }
    if (author) {
      query.author = new RegExp(author, 'i'); // 不区分大小写的模糊匹配
    }
    if (keyword) {
      query.$or = [
        { title: new RegExp(keyword, 'i') },
        { author: new RegExp(keyword, 'i') },
        { description: new RegExp(keyword, 'i') },
      ];
    }

    // 计算跳过的文档数
    const skip = (page - 1) * limit;

    // 构建排序对象
    const sort: any = {};
    sort[sortBy] = order === 'asc' ? 1 : -1;

    // 执行查询
    const [books, total] = await Promise.all([
      Book.find(query)
        .sort(sort)
        .skip(skip)
        .limit(limit)
        .lean(), // 使用 lean() 返回普通 JavaScript 对象，提高性能
      Book.countDocuments(query),
    ]);

    // 计算分页信息
    const totalPages = Math.ceil(total / limit);
    const hasNextPage = page < totalPages;
    const hasPrevPage = page > 1;

    logger.info(`查询图书列表成功，共 ${total} 条记录`);

    res.status(200).json({
      success: true,
      message: '查询图书列表成功',
      data: {
        books,
        pagination: {
          currentPage: page,
          totalPages,
          totalItems: total,
          itemsPerPage: limit,
          hasNextPage,
          hasPrevPage,
        },
      },
    });
  } catch (error) {
    logger.error('查询图书列表失败:', error);
    res.status(500).json({
      success: false,
      message: '查询图书列表失败',
      error: error instanceof Error ? error.message : '未知错误',
    });
  }
};

/**
 * GET /api/books/:id
 * 根据 ID 查询单本图书信息
 */
export const getBookById = async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;

    // 验证 ID 格式
    if (!id || id.trim() === '') {
      res.status(400).json({
        success: false,
        message: '图书 ID 不能为空',
      });
      return;
    }

    // 查询图书
    const book = await Book.findById(id);

    if (!book) {
      logger.warn(`图书不存在: ID=${id}`);
      res.status(404).json({
        success: false,
        message: '图书不存在',
      });
      return;
    }

    logger.info(`查询图书成功: ${book.title}`);

    res.status(200).json({
      success: true,
      message: '查询图书成功',
      data: book,
    });
  } catch (error) {
    logger.error('查询图书失败:', error);
    
    // 处理无效的 MongoDB ObjectId 格式
    if (error instanceof Error && error.name === 'CastError') {
      res.status(400).json({
        success: false,
        message: '无效的图书 ID 格式',
      });
      return;
    }

    res.status(500).json({
      success: false,
      message: '查询图书失败',
      error: error instanceof Error ? error.message : '未知错误',
    });
  }
};

/**
 * POST /api/books
 * 新增一本图书
 * 请求体参数：title, author, publishDate, price, isbn, publisher, category, description, stock
 */
export const createBook = async (req: Request, res: Response): Promise<void> => {
  try {
    const { title, author, publishDate, price, isbn, publisher, category, description, stock } = req.body;

    // 验证必填参数
    if (!title || title.trim() === '') {
      res.status(400).json({
        success: false,
        message: '书名不能为空',
      });
      return;
    }

    if (!author || author.trim() === '') {
      res.status(400).json({
        success: false,
        message: '作者不能为空',
      });
      return;
    }

    if (!publishDate) {
      res.status(400).json({
        success: false,
        message: '出版日期不能为空',
      });
      return;
    }

    if (price === undefined || price === null) {
      res.status(400).json({
        success: false,
        message: '价格不能为空',
      });
      return;
    }

    // 验证价格格式
    const priceNum = parseFloat(price);
    if (isNaN(priceNum) || priceNum < 0) {
      res.status(400).json({
        success: false,
        message: '价格格式不正确或不能为负数',
      });
      return;
    }

    // 验证出版日期格式
    const publishDateObj = new Date(publishDate);
    if (isNaN(publishDateObj.getTime())) {
      res.status(400).json({
        success: false,
        message: '出版日期格式不正确',
      });
      return;
    }

    // 检查 ISBN 是否已存在
    if (isbn) {
      const existingBook = await Book.findOne({ isbn });
      if (existingBook) {
        res.status(409).json({
          success: false,
          message: `ISBN ${isbn} 已存在`,
        });
        return;
      }
    }

    // 创建图书
    const book = new Book({
      title: title.trim(),
      author: author.trim(),
      publishDate: publishDateObj,
      price: priceNum,
      isbn: isbn?.trim(),
      publisher: publisher?.trim(),
      category: category?.trim(),
      description: description?.trim(),
      stock: stock !== undefined ? parseInt(stock) : 0,
    });

    // 保存到数据库
    await book.save();

    logger.info(`新增图书成功: ${book.title} (ID: ${book._id})`);

    res.status(201).json({
      success: true,
      message: '新增图书成功',
      data: book,
    });
  } catch (error) {
    logger.error('新增图书失败:', error);

    // 处理 Mongoose 验证错误
    if (error instanceof Error && error.name === 'ValidationError') {
      res.status(400).json({
        success: false,
        message: '数据验证失败',
        error: error.message,
      });
      return;
    }

    res.status(500).json({
      success: false,
      message: '新增图书失败',
      error: error instanceof Error ? error.message : '未知错误',
    });
  }
};

/**
 * PUT /api/books/:id
 * 更新图书信息
 */
export const updateBook = async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;
    const updateData = req.body;

    // 验证 ID
    if (!id || id.trim() === '') {
      res.status(400).json({
        success: false,
        message: '图书 ID 不能为空',
      });
      return;
    }

    // 检查图书是否存在
    const existingBook = await Book.findById(id);
    if (!existingBook) {
      res.status(404).json({
        success: false,
        message: '图书不存在',
      });
      return;
    }

    // 如果更新 ISBN，检查是否与其他图书冲突
    if (updateData.isbn && updateData.isbn !== existingBook.isbn) {
      const duplicateBook = await Book.findOne({ isbn: updateData.isbn });
      if (duplicateBook) {
        res.status(409).json({
          success: false,
          message: `ISBN ${updateData.isbn} 已被其他图书使用`,
        });
        return;
      }
    }

    // 更新图书
    const updatedBook = await Book.findByIdAndUpdate(
      id,
      { $set: updateData },
      { 
        new: true, // 返回更新后的文档
        runValidators: true, // 运行验证器
      }
    );

    logger.info(`更新图书成功: ${updatedBook?.title} (ID: ${id})`);

    res.status(200).json({
      success: true,
      message: '更新图书成功',
      data: updatedBook,
    });
  } catch (error) {
    logger.error('更新图书失败:', error);

    if (error instanceof Error && error.name === 'CastError') {
      res.status(400).json({
        success: false,
        message: '无效的图书 ID 格式',
      });
      return;
    }

    if (error instanceof Error && error.name === 'ValidationError') {
      res.status(400).json({
        success: false,
        message: '数据验证失败',
        error: error.message,
      });
      return;
    }

    res.status(500).json({
      success: false,
      message: '更新图书失败',
      error: error instanceof Error ? error.message : '未知错误',
    });
  }
};

/**
 * DELETE /api/books/:id
 * 根据 ID 删除一本图书
 */
export const deleteBook = async (req: Request, res: Response): Promise<void> => {
  try {
    const { id } = req.params;

    // 验证 ID
    if (!id || id.trim() === '') {
      res.status(400).json({
        success: false,
        message: '图书 ID 不能为空',
      });
      return;
    }

    // 删除图书
    const deletedBook = await Book.findByIdAndDelete(id);

    if (!deletedBook) {
      logger.warn(`删除失败，图书不存在: ID=${id}`);
      res.status(404).json({
        success: false,
        message: '图书不存在',
      });
      return;
    }

    logger.info(`删除图书成功: ${deletedBook.title} (ID: ${id})`);

    res.status(200).json({
      success: true,
      message: '删除图书成功',
      data: {
        id: deletedBook._id,
        title: deletedBook.title,
      },
    });
  } catch (error) {
    logger.error('删除图书失败:', error);

    if (error instanceof Error && error.name === 'CastError') {
      res.status(400).json({
        success: false,
        message: '无效的图书 ID 格式',
      });
      return;
    }

    res.status(500).json({
      success: false,
      message: '删除图书失败',
      error: error instanceof Error ? error.message : '未知错误',
    });
  }
};

/**
 * GET /api/books/stats/summary
 * 获取图书统计信息
 */
export const getBookStats = async (req: Request, res: Response): Promise<void> => {
  try {
    const [totalBooks, totalValue, categories] = await Promise.all([
      Book.countDocuments(),
      Book.aggregate([
        {
          $group: {
            _id: null,
            total: { $sum: { $multiply: ['$price', '$stock'] } },
          },
        },
      ]),
      Book.aggregate([
        {
          $group: {
            _id: '$category',
            count: { $sum: 1 },
          },
        },
        { $sort: { count: -1 } },
      ]),
    ]);

    res.status(200).json({
      success: true,
      message: '获取统计信息成功',
      data: {
        totalBooks,
        totalValue: totalValue[0]?.total || 0,
        categoryStats: categories,
      },
    });
  } catch (error) {
    logger.error('获取统计信息失败:', error);
    res.status(500).json({
      success: false,
      message: '获取统计信息失败',
      error: error instanceof Error ? error.message : '未知错误',
    });
  }
};

export default {
  getAllBooks,
  getBookById,
  createBook,
  updateBook,
  deleteBook,
  getBookStats,
};
